﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Tzx.TUpdater.Utilities;
using Tzx.TUpdater.WinBuilder;
using Tzx.TUpdater.WinHelp;
using Tzx.TUpdater.WinUpdater;

namespace Tzx.TUpdater
{
    /// <summary>
    /// 调用exe的参数要与qupdater兼容
    /// </summary>
    static class Program
    {
        public const string Args_checkforupdates= "checkforupdates"; //检查更新数量,返回int(兼容qupdater)
        public const string Args_run            = "run";             //运行
        public const string Args_checkrun       = "checkrun";        //检查更新并运行
        public const string Args_url            = "url";             //更新的服务端地址
        public const string Args_gen            = "gen";             //服务端配置文件生成操作界面
        public const string Args_help           = "help";            //帮助向导
        public const string Args_help2          = "?";               //帮助向导
        

        /// <summary>
        /// 应用程序的主入口点
        /// </summary>
        [STAThread]
        static int Main(string[] args)
        {
            AppGlobal.LogFileCheck();//检查日志文件是否超大

            AppGlobal.Log("----------------------------------------"); //日志开始

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            #region 处理未捕获异常

            //处理未捕获的异常
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

            //处理UI线程异常
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            //处理非UI线程异常
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

            #endregion

            //初始化
            AppGlobal.InitializeIniFile();      //初始化Ini配置文件
            AppGlobal.InitializeLocalXmlFile(); //初始化Xml更新信息

            //0.没有参数
            if (args == null || args.Length == 0)
            {
                //Application.Run(new WizardFrm()); //向导帮助

                //为兼容qupdater,无参数则检查更新
                //int count = new AppUpdater().CheckForUpdate();//检查,若有更新则执行更新
                //int count = AppUpdater.GetMe().CheckForUpdate();//检查,若有更新则执行更新
                //if (count > 0)
                //{
                    Application.Run(new UpdaterFrm());
                //}

                //return count;
            }
            
            //1.1.打开配置生成界面
            bool existGen = ExistArgument(args, Args_gen);
            if (existGen)
            {
                Application.Run(new ServerConfigBuilderFrm());
                return 0;
            }

            //1.2.打开帮助界面
            bool existHelp = ExistArgument(args, Args_help) || ExistArgument(args, Args_help2);
            if (existHelp)
            {
                Application.Run(new WizardFrm()); //向导帮助
                return 0;
            }

            //2.传入了url参数,则更新配置
            string url = GetArgumentValue(args, Args_url);
            if (!string.IsNullOrEmpty(url))
            {
                AppGlobal.IniUpdaterUrl = url;
            }

            //3.检查ini配置
            if (string.IsNullOrEmpty(AppGlobal.IniUpdaterUrl))
            {
                string msg = "没有配置更新服务器Url列表地址，请在Ini配置文件“" + IniHelper.GetDefaultIniFile() + "”中配置。"
                             + Environment.NewLine + "示例："
                             + AppGlobal.IniKeyUpdateinfoListURL + " = http://www.abc.com/Updater/";
                AppGlobal.Log(msg);
                MessageBox.Show(msg,AppGlobal.AppNameText, MessageBoxButtons.OK, MessageBoxIcon.Error,
                                MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification);
                return -1;
            }

            #region 更新操作

            //5.1.检查待更新文件的个数(调用EXE的返回值)
            bool existCheckUpdates = ExistArgument(args, Args_checkforupdates);
            if (existCheckUpdates)
            {
                AppGlobal.LogDebug("存在检查更新参数" + Args_checkforupdates + ",下面检查更新文件个数");
                int count = AppUpdater.GetMe().CheckForUpdate();//待更新文件的个数
                AppGlobal.LogDebug("更新文件有 " + count + " 个");
                return count;//exe返回待更新文件的个数
            }

            //5.2.运行更新窗体
            bool existRun = ExistArgument(args, Args_run);
            if (existRun)
            {
                AppGlobal.LogDebug("存在运行更新窗体参数" + Args_run + ",下面打开更新界面");
                Application.Run(new UpdaterFrm());
            }

            //5.3.先检查更新文件个数,若有则执行更新
            bool existCheckRun = ExistArgument(args, Args_checkrun);
            if (existCheckRun)
            {
                AppGlobal.LogDebug("存在更新参数" + Args_checkrun + ",下面检查更新");
                int count = AppUpdater.GetMe().CheckForUpdate();//检查,若有更新则执行更新
                if (count > 0)
                {
                    AppGlobal.LogDebug("检查到有" + count + "个文件");
                    Application.Run(new UpdaterFrm());//自动进入下一步
                }
            }

            #endregion

            //
            return 0;
        }

        #region 帮助方法 - 参数

        /// <summary>
        /// 是否存在某个参数
        /// </summary>
        /// <param name="args">传入的参数数组</param>
        /// <param name="argument">判断是否存在此参数</param>
        /// <returns>是否存在</returns>
        private static bool ExistArgument(IEnumerable<string> args, string argument)
        {
            if (args == null || string.IsNullOrEmpty(argument))
            {
                return false;
            }

            argument = argument.TrimStart('-', '/');
            if (argument == string.Empty)
            {
                return false;
            }

            foreach (string s in args)
            {
                string sArg = s.TrimStart('-', '/');
                if (sArg == string.Empty)
                {
                    continue;
                }

                if (String.Compare(sArg, argument, StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 获得某一参数键的值
        /// </summary>
        /// <param name="args">传入的参数数组</param>
        /// <param name="argumentKey">参数Key</param>
        /// <returns>参数Value</returns>
        private static string GetArgumentValue(IEnumerable<string> args, string argumentKey)
        {
            if (args == null || string.IsNullOrEmpty(argumentKey))
            {
                return null;
            }

            argumentKey = argumentKey.ToLower().TrimStart('-', '/');//小写,去参数前缀
            if (argumentKey == string.Empty)
            {
                return null;
            }

            foreach (string arg in args)
            {
                if (arg == null)
                {
                    continue;
                }
                string arg2 = arg.ToLower().TrimStart('-', '/');//小写,去参数前缀
                if (arg2 == string.Empty)
                {
                    continue;
                }

                string prefix = argumentKey + ":";
                if (arg2.StartsWith(prefix))
                {
                    string argumentValue = arg2.Substring(prefix.Length);
                    return argumentValue;
                }
            }
            return null;
        }

        #endregion

        #region 处理未捕获异常

        /// <summary>
        /// 
        /// </summary>
        static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            Exception appEx = e.Exception;
            ExceptionMethod(appEx);
        }

        /// <summary>
        /// 
        /// </summary>
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Exception appEx = e.ExceptionObject as Exception;
            ExceptionMethod(appEx);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="appEx"></param>
        private static void ExceptionMethod(Exception appEx)
        {
            if (appEx == null)
            {
                MessageBox.Show("程序出现未知空异常", "未处理错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            //记录异常日志
            try
            {
                AppGlobal.Log(appEx);
            }
            catch (Exception ex)
            {
                MessageBox.Show("记录异常日志出错：" + ex.Message, "未处理错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            //返回消息给用户
            string msg = string.Format("程序出现未处理异常，错误消息如下：{0}{1}{2}", 
                Environment.NewLine, 
                appEx.Message,
                Environment.NewLine);
            MessageBox.Show(msg, "未处理错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #endregion

    }

}
